package com.cy;

import com.cy.pj.sys.service.realm.ShiroRealm;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;


@EnableCaching //开启springboot内置缓存
@SpringBootApplication
public class AdminApplication {
    public static void main(String[] args) {
        SpringApplication.run(AdminApplication.class,args);
    }

    /**
     * 配置Realm对象(org.apache.shiro.realm.Realm)
     * @Bean注解描述方法时，表示方法的返回值要交给spring管理
     * @return
     */
    @Bean
    public Realm realm(){
        return new ShiroRealm();
    }

    /**定义过滤规则(Shiro框架中提供了很多过滤器-Filter,它会对请求中的信息进行过滤，假如这些请求需要认证才可访问，则需要先登录认证)
     * 例如在一些订票系统中，查询票信息不需要登陆，但是访问订单信息或进行订单创建时则需要登录，这些都称之为规则
     *
     * 匿名过滤器应该在认证过滤器的前面设置,应该先放行不需要认证的路径
     * 拦截器的优先级是从上到下，从左到右，如果有匹配的拦截器就会阻断并返回。
     */
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        //过滤链对象的定义(这个过滤链中包含了很多内置过滤器)
        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
        //指定过滤链中的过滤规则,例如：
        //配置/menu/*开头的资源，可以匿名访问(不用登录就可以访问),其中anon为shiro框架指定的匿名过滤器
//        chainDefinition.addPathDefinition("/menu/*","anon");
        chainDefinition.addPathDefinition("/user/login/**","anon");
        chainDefinition.addPathDefinition("/user/logout","logout");
        //配置以/**开头的资源必须都要经过认证，其中authc为shiro框架指定的认证过滤器
//        chainDefinition.addPathDefinition("/**", "authc");
        //配置了记住我的功能，需要将过滤器设置为user
        chainDefinition.addPathDefinition("/**", "user");
        return chainDefinition;
    }

    /*配置session管理器对象*/
    @Bean
    public SessionManager sessionManager(){
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
//        session的超时时间
        sessionManager.setGlobalSessionTimeout(60*60*1000);
//        删除无效session
        sessionManager.setDeleteInvalidSessions(true);
//        当客户端cookie被禁用时是否要设置url重写
        sessionManager.setSessionIdUrlRewritingEnabled(false);
        return sessionManager;
    }

    /**
     * 记住我
     * @return
     */
    @Bean
    public RememberMeManager rememberMeManager(){
        CookieRememberMeManager cManager = new CookieRememberMeManager();
        //设置rememberMe的Cookie名称
        SimpleCookie simpleCookie = new SimpleCookie("remeberMe");
        simpleCookie.setMaxAge(7*24*60*60);//7天
        cManager.setCookie(simpleCookie);
        //设置加密解密密钥，使之密钥固定
        cManager.setCipherKey(Base64.decode("6ZmI6I2j5Y+R5aSn5ZOlAA=="));
        return cManager;
    }

    /**
     *配置Shiro中自带的CacheManager对象，此对象可以通过
     * Cache缓存授权时获取到权限信息，下次再访问授权方法时不需要再查用户权限
     * @return
     */
    @Bean
    protected CacheManager shiroCacheManager(){
        return new MemoryConstrainedCacheManager();
    }

    @Bean
    protected DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);//让目标对象上的注解映射是生效
        return defaultAdvisorAutoProxyCreator;
    }

}
